package com.singfee.gisservice.service.impl;

import com.singfee.gisservice.entity.*;
import com.singfee.gisservice.function.PostGISFunction;
import com.singfee.gisservice.mapper.PostGISMapper;
import com.singfee.gisservice.service.IPostGISServer;
import io.micrometer.common.util.StringUtils;
import org.postgresql.shaded.com.ongres.scram.common.util.Preconditions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;

@Service
public class PostGISServerImpl  implements IPostGISServer {
    @Autowired
    PostGISMapper pgmapper;

    @Override
    public String getFeatureList(String layerName, String filter) {
        List<String> fields = getFieldsWithoutGeom(layerName);

        Params params = new Params().put("table", layerName).put("filter", filter).put("fields", fields);
        return pgmapper.getFeatures(params);
    }

    @Override
    public List<Map> getFeatureInfo(String layerName, String filter) {
        List fields = getFieldsWithoutGeom(layerName);
        List<Map> list = getFeatureInfo(layerName, fields, filter);
        return list;
    }

    @Override
    public HashMap<String, String> identify(String[] layers, Ewkt point,String filterField) {
        //注意处理提交过来的图层名称是否有重复的
        ArrayList<String> tempLyrNams = new ArrayList();
        for (String lyrName : layers) {
            if (!tempLyrNams.contains(lyrName)) {
                tempLyrNams.add(lyrName);
            }
        }
        HashMap<String, String> results = new HashMap<>();
        for (String lyrName : tempLyrNams) {
            String filter = "st_contains(geom, st_geomfromewkt('" + point.getEwkt() + "'))";
            if(StringUtils.isNotEmpty(filterField))
            {
                filter+=" and "+filterField;
            }
            String item = getFeatureList(lyrName, filter);
            results.put(lyrName, item);
        }
        return results;
    }

    private List<Map> getFeatureInfo(String layerName, List fields, String filter) {
        Params params = new Params().put("table", layerName).put("filter", filter).put("fields", fields);
        List<Map> list = pgmapper.getFeatureInfo(params);
        return list;
    }

    public List<String> getFieldsWithoutGeom(String table) {
        StringBuilder sql =new StringBuilder();
        sql.append("select array_to_string(array_agg(s.column_name),',') as fields FROM information_schema.COLUMNS s ");
        sql.append("WHERE s.table_name = '" + table + "' AND s.column_name <> 'geom' ");
        //<add singfee 2024-1-24>
        //过滤掉业务系统不需要展示的字段
        List<String> filterFields =getFilterFields(table);
        if(filterFields!=null&&filterFields.size()>0) {
            sql.append("AND s.column_name not in (");
           int size =filterFields.size();
            for ( int i=0; i< size;i++)
            {
                String field= filterFields.get(i);
                if(i!=size-1)
                {
                    sql.append("'"+field+"',");
                }
                else {
                    sql.append("'"+field+"'");
                }
            }
            sql.append(");");
        }
        //</add>
        List<Map> list = pgmapper.sqlRun(sql.toString());
        Preconditions.checkArgument((list.size() > 0 && list.get(0) != null), "表" + table + "不存在");
        return Arrays.asList(list.get(0).get("fields").toString().split(","));
    }

    private List<String> getFilterFields(String layerName)
    {
        String strSql="select array_to_string(array_agg(s.field_name),',') as fields from bus_layer_hide_field s where layer_name='"+layerName+"';";
        List<Map> list = pgmapper.sqlRun(strSql.toString());
        if(list!=null&&list.size()>0&&list.get(0)!=null) {
            return Arrays.asList(list.get(0).get("fields").toString().split(","));
        }
        else {
            return null;
        }
    }

    public Geom ST_GeomFromEWKT(Ewkt ewkt) {
        Function function = new PostGISFunction().ST_GeometryFromText(ewkt);
        List list = pgmapper.geometryOperator(function);
        Preconditions.checkArgument(list.size() == 1, "创建geom非唯一");
        String result = (String) list.get(0);
        return new Geom(result);
    }

    @Override
    public String selectGeometryById(String layerName, Integer fId) {
        String filter = "id =" + fId;
        return  getFeatureList(layerName, filter);
    }

    @Override
    public String selectByPolygon(String layerName, Ewkt ewkt, MyList property) {
        Geom polygon=ST_GeomFromEWKT(ewkt);
        Function ifIntersect = new PostGISFunction().ST_Intersects(polygon, new Geom(new Function("t.geom")));
        Params params = new Params().put("filter", ifIntersect).put("table", layerName).put("fields", property);
        return  pgmapper.getFeatures(params);
    }

    @Override
    public String clipByPolygonWithProperties(String layerName,MyList properties,Ewkt ewkt) {
        Geom polygon=ST_GeomFromEWKT(ewkt);
        Function ifIntersect = new PostGISFunction().ST_Intersects(polygon, new Geom(new Function("t.geom")));
        Function select = new PostGISFunction().ST_AsGeoJSON(new Geom(new PostGISFunction().ST_Intersection_SqlString("t.geom", polygon.toString())));
        Params params = new Params().put("geom", select).put("filter", ifIntersect).put("table", layerName).put("fields", properties);
        String geoJson = pgmapper.getFeatures(params);
        return geoJson;
    }

    @Override
    public List<Map> TotalArea(String layerName, Ewkt ewkt,MyList fields)
    {
        Geom polygon=ST_GeomFromEWKT(ewkt);
        Function ifIntersect = new PostGISFunction().ST_Intersects(polygon, new Geom(new Function("t.geom")));
        Function select = new PostGISFunction().ST_AsGeoJSON(new Geom(new PostGISFunction().ST_Intersection_SqlString("t.geom", polygon.toString())));
        Params params = new Params().put("geom", select).put("filter", ifIntersect).put("table", layerName).put("fields",fields);
        return pgmapper.totalArea(params);
    }

    @Override
    public boolean addFeature(String layerName,Ewkt ewkt)
    {
        Geom geom=ST_GeomFromEWKT(ewkt);
        return false;//pgmapper.addFeature(layerName,geom);
    }
}
